﻿using ChargeCard.Web.Models;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;
using System.Collections.Generic;

namespace ChargeCard.Web.Tests.Models
{
    
    
    /// <summary>
    ///This is a test class for IVoucherRepositoryTest and is intended
    ///to contain all IVoucherRepositoryTest Unit Tests
    ///</summary>
    [TestClass()]
    public class IVoucherRepositoryTest
    {
        private TestContext testContextInstance;
        private const string SAMPLE_PIN = "h23u4y294";

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            DatabaseHelper.CleanupDatabase();
        }
        
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        

        [TestInitialize()]
        public void MyTestInitialize()
        {
            DatabaseHelper.InitializeDatabase();
        }
        
        [TestCleanup()]
        public void MyTestCleanup()
        {
            DatabaseHelper.CleanupDatabase();
        }

        #endregion


        internal virtual IVoucherRepository CreateIVoucherRepository()
        {
            IVoucherRepository target = new VoucherRepository();
            return target;
        }

        /// <summary>
        ///A test for DeleteVoucher
        ///</summary>
        [TestMethod()]
        public void DeleteVoucherTest()
        {
            IVoucherRepository target = CreateIVoucherRepository();
            Assert.IsNotNull(target.GetVoucherByPin(SAMPLE_PIN));
            target.DeleteVoucher(SAMPLE_PIN);
            target.Persist();
            Assert.IsNull(target.GetVoucherByPin(SAMPLE_PIN));
        }

        /// <summary>
        ///A test for FindVouchers
        ///</summary>
        [TestMethod()]
        public void FindVouchersTest()
        {
            IVoucherRepository target = CreateIVoucherRepository(); // TODO: Initialize to an appropriate value
            int provider = 1; 
            int priceType = 1; 
            IList<Voucher> actual;
            actual = target.FindVouchers(provider, priceType, 2);

            Assert.IsNotNull(actual);
            Assert.AreEqual(2, actual.Count);

            Voucher result = actual.SingleOrDefault<Voucher>(v => v.PlainPIN == SAMPLE_PIN);
            Assert.IsNotNull(result, String.Format("PIN {0} not found in result set!",SAMPLE_PIN));
            Assert.AreEqual(result.Status, 5, "result status wasn't 5.");

            actual = target.FindVouchers(provider, 5);

            Assert.IsNotNull(actual);
            Assert.AreEqual(5, actual.Count);

            result = actual.SingleOrDefault<Voucher>(v => v.PlainPIN == SAMPLE_PIN);
            Assert.IsNotNull(result, String.Format("PIN {0} not found in result set!",SAMPLE_PIN));
            Assert.AreEqual(result.Status, 5, "result status wasn't 5.");
        }

        /// <summary>
        ///A test for GetVoucherById
        ///</summary>
        [TestMethod()]
        public void GetVoucherByIdTest()
        {
            IVoucherRepository target = CreateIVoucherRepository();
            Voucher actual;
            actual = target.GetVoucherByPin(SAMPLE_PIN);
            Assert.IsNotNull(actual);
            Assert.AreEqual(SAMPLE_PIN, actual.PlainPIN);
        }

        /// <summary>
        ///A test for ImportVouchers
        ///</summary>
        [TestMethod()]
        public void ImportVouchersTest()
        {
            IVoucherRepository target = CreateIVoucherRepository();
            IList<Voucher> vouchers = new List<Voucher>();

            vouchers.Add(new Voucher
            {
                PlainPIN = "abc",
                ImportDate = DateTime.Now,
                LastUpdateDate = DateTime.Now,
                PriceTypeId = 1,
                ProviderId = 2,
                Status = 3
            });

            vouchers.Add(new Voucher
            {
                PlainPIN = "abcd",
                ImportDate = DateTime.Now,
                LastUpdateDate = DateTime.Now,
                PriceTypeId = 1,
                ProviderId = 3,
                Status = 3
            });


            target.ImportVouchers(vouchers);
            target.Persist();

            Voucher v1 = target.GetVoucherByPin("abc");
            Assert.IsNotNull(v1);
            Assert.AreEqual(v1.ProviderId, 2);

            Voucher v2 = target.GetVoucherByPin("abcd");
            Assert.IsNotNull(v2);
            Assert.AreEqual(v2.ProviderId, 3);
        }

        [TestMethod()]
        public void ImportDuplicateVouchersTest()
        {
            IVoucherRepository target = CreateIVoucherRepository();
            IList<Voucher> vouchers = new List<Voucher>();

            vouchers.Add(new Voucher
            {
                PlainPIN = SAMPLE_PIN,
                ImportDate = DateTime.Now,
                LastUpdateDate = DateTime.Now,
                PriceTypeId = 1,
                ProviderId = 2,
                Status = 3
            });


            try
            {
                target.ImportVouchers(vouchers);
                Assert.Fail(String.Format("ImportVouchers Should not accept duplicate pin: {0}",SAMPLE_PIN));
            }
            catch (DuplicatePinException ex)
            {
                Assert.AreEqual(SAMPLE_PIN, ex.Pin);
            }
            
        }

        /// <summary>
        ///A test for Persist
        ///</summary>
        [TestMethod()]
        public void PersistTest()
        {
            IVoucherRepository target = CreateIVoucherRepository(); 
            Voucher voucher = target.GetVoucherByPin(SAMPLE_PIN);
            Assert.IsNotNull(voucher);
            voucher.Status = 4;
            target.Persist();
            voucher = target.GetVoucherByPin(SAMPLE_PIN);
            Assert.AreEqual(4, voucher.Status);
        }
    }
}
